package com.sojson.util.serialize.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import com.sojson.util.StringUtil;
import com.sojson.util.serialize.SerializeUtilInterface;

/**
 * 序列化工具类实现类
 * 
 * @author liu
 * @Date 2020-06-15 14:51:09
 * @Description
 *
 */
public class SerializeUtilImpl implements SerializeUtilInterface {

    private static SerializeUtilImpl serializeUtilImpl;

    private SerializeUtilImpl() {}

    /**
     * 将对象转换为字节数组
     * 
     * @param value 要转换的对象
     * @return 转换后的数组
     * @throws IOException
     */
    @Override
    public byte[] serialize(Object value) throws IOException {
        if (isBlankObject(value)) {
            throw new NullPointerException("Can't serialize null");
        }
        byte[] rv = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream os = null;
        bos = new ByteArrayOutputStream();
        try {
            os = new ObjectOutputStream(bos);
            os.writeObject(value);
            os.close();
            bos.close();
            rv = bos.toByteArray();
        } finally {
            closes(os, bos);
        }
        return rv;
    }

    /**
     * 将字节数组转换为Object类型的对象
     * 
     * @param in 要转换的字节数组
     * @return 转换后的对象
     * @throws IOException
     * @throws ClassNotFoundException
     */
    @Override
    public Object deserialize(byte[] in) throws ClassNotFoundException, IOException {
        return deserialize(in, Object.class);
    }

    /**
     * 将字节数组转换为指定类型的对象
     * 
     * @param in 要转换的字节数组
     * @param requiredType 转换后的对象的类型
     * @return 转换后的对象
     * @throws IOException
     * @throws ClassNotFoundException
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T deserialize(byte[] in, Class<T> requiredType) throws IOException, ClassNotFoundException {
        Object rv = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream is = null;
        try {
            if (in != null) {
                bis = new ByteArrayInputStream(in);
                is = new ObjectInputStream(bis);
                rv = is.readObject();
            }
        } finally {
            closes(is, bis);
        }
        return (T)rv;
    }

    /**
     * 关闭资源
     * 
     * @param closeable
     * @throws IOException
     */
    @SuppressWarnings("unused")
    private static void close(Closeable closeable) throws IOException {
        if (closeable != null) {
            closeable.close();
        }
    }

    /**
     * 关闭资源
     * 
     * @param closeable
     * @throws IOException
     */
    private static void closes(Closeable... closeables) throws IOException {
        for (Closeable closeable : closeables) {
            if (closeable != null) {
                closeable.close();
            }
        }
    }

    /**
     * 判断一个对象是否是空(空对象)
     * 
     * @param obj
     * @return
     */
    private static boolean isBlankObject(Object obj) {
        return StringUtil.isBlankObject(obj);
    }

    public static SerializeUtilImpl getInstances() {
        if (isBlankObject(serializeUtilImpl)) {
            serializeUtilImpl = new SerializeUtilImpl();
        }
        return serializeUtilImpl;
    }

}